local _G = GLOBAL
--=======================================
--[[ 本地函数 ]]
--=======================================
-- 移除预制物(预制物,数量)
local function removeItem(item, num)
    if item.components.stackable then
        item.components.stackable:Get(num):Remove()
    else
        item:Remove()
    end
end
--=======================================
--[[ 动作定义 ]]
--=======================================
local actions = {
    SW_FRESHEN = {
        id = "SW_FRESHEN",
        priority = 6,
        strfn = function(act)
            return "GENERIC"
        end,
        fn = function(act)
            if act.target ~= nil and act.invobject ~= nil and act.invobject.components.sw_freshen ~= nil
                and (act.target:HasTag("fresh") or act.target:HasTag("stale") or act.target:HasTag("spoiled")) then
                act.target.components.perishable:SetPercent(act.target.components.perishable:GetPercent() + (
                    act.invobject.components.sw_freshen.divide_effect_by_stack_size and
                    act.target.components.stackable and
                    act.invobject.components.sw_freshen.percent_increase / act.target.components.stackable.stacksize or
                    act.invobject.components.sw_freshen.percent_increase
                ))

                local used_item = act.doer.components.inventory:RemoveItem(act.invobject)
                if used_item ~= nil then
                    SpawnPrefab("firesplash_fx").Transform:SetPosition(act.target.Transform:GetWorldPosition())
                    if act.doer.SoundEmitter ~= nil then
                        act.doer.SoundEmitter:PlaySound("dontstarve/common/fireAddFuel")
                    end
                    used_item:Remove()
                    return true
                else
                    return false
                end
            else
                return false
            end
        end,
    },
    SW_UPGRADE = {
        id = "SW_UPGRADE",
        priority = 6,
        strfn = function(act)
            if act.target and act.target:HasTag("sw_pigweed_pouch") then
                return "INFLOOD"
            end
            if act.target and act.target:HasTag("tent") then
                return "INFLOOD"
            end
            return "GENERIC"
        end,
        fn = function(act)
            local target = act.target
            local invobject = act.invobject
            if target ~= nil and invobject ~= nil and invobject.components.sw_shard ~= nil
                and target.components.sw_upgrade ~= nil then
                local shard_type = invobject.prefab == "sw_enlight_shard" and "enlight" or "shadow"
                if target.components.sw_upgrade ~= nil then
                    -- 执行升级
                    local ok, err = target.components.sw_upgrade:DoUpgrade(shard_type)
                    if ok then
                        -- 移除升级物品
                        local used_item = act.doer.components.inventory:RemoveItem(invobject)
                        if used_item ~= nil then
                            used_item:Remove()
                            return true
                        else
                            return false
                        end
                    else
                        return false, err
                    end
                end
            else
                return false
            end
        end,
    },
    SW_WOVEN = {
        id = "SW_WOVEN",
        priority = 6,
        strfn = function(act)
            return "GENERIC"
        end,
        fn = function(act)
            local target = act.target
            local invobject = act.invobject
            if target ~= nil and invobject ~= nil and target.components.sw_weavable ~= nil then
                target.components.sw_weavable:DoWeave(target, invobject, act.doer)
                local used_item = act.doer.components.inventory:RemoveItem(invobject)
                if used_item ~= nil then
                    SpawnPrefab("chestupgrade_stacksize_fx").Transform:SetPosition(target.Transform:GetWorldPosition())
                    used_item:Remove()
                end
                return true
            end
            return false
        end,
    },
    SW_CORDON = {
        id = "SW_CORDON",
        priority = 6,
        strfn = function(act)
            return "GENERIC"
        end,
        fn = function(act)
            local target = act.target
            local invobject = act.invobject
            if target ~= nil and invobject ~= nil and target.components.sw_cordon ~= nil and target.components.sw_cordon.cordon == false then
                target.components.sw_cordon.cordon = true
                SendModRPCToShard(SHARD_MOD_RPC.SHADOWWOVEN.Cordon, target.components.worldmigrator.linkedWorld, target.components.worldmigrator.id, true)
                invobject:Remove()
                local stone = SpawnPrefab("sw_infernal_stone")
                -- stone.entity:SetParent(target.entity)
                target:AddChild(stone)
                stone.Transform:SetPosition(0, 0, 0)

                if TheWorld and TheWorld.components.sw_sealsinkholemanager then
                    TheWorld.components.sw_sealsinkholemanager:RefreshUnbalanceState()
                end
                return true
            end
            return false, "ALREADY_CORDON"
        end,
    },
    SW_PIGBOT = {
        id = "SW_PIGBOT",
        priority = 6,
        strfn = function(act)
            return "GENERIC"
        end,
        fn = function(act)
            local target = act.target
            local invobject = act.invobject
            if target ~= nil and target.NotNeedFuelToWork ~= nil and target.NotNeedFuelToWork == false then
                target.NotNeedFuelToWork = true
                invobject:Remove()
                return true
            end
            return false, "ALREADY_UPDATED"
        end,
    },
    SW_TRADE = {
        id = "SW_TRADE",
        priority = 6,
        strfn = function(act)
            return "GENERIC"
        end,
        fn = function(act)
            local target = act.target
            local invobject = act.invobject
            local doer = act.doer
            if target == nil or invobject == nil or doer == nil then
                return false
            end
            if target.prefab == "sw_moonlight_glass_tree" and TheWorld.components.sw_sealsinkholemanager.is_strong_unbalanced and (not TheWorld:HasTag("cave")) then
                invobject:Remove()
                target.components.lootdropper:SpawnLootPrefab("sw_moonlight_seed")
                return true
            elseif target.prefab == "sw_shadow_tree" and TheWorld.components.sw_sealsinkholemanager.is_strong_unbalanced and TheWorld:HasTag("cave") then
                invobject:Remove()
                target.components.lootdropper:SpawnLootPrefab("sw_shadow_seed")
                return true
            else
                return false, "NOT_ELIGIBLE"
            end
        end,
    },
}

for _, action in pairs(actions) do
    local _action = Action()
    for k, v in pairs(action) do
        _action[k] = v
    end
    AddAction(_action)
end

--=======================================
--[[ 动作行为:就是执行动作的人物动画 ]]
--=======================================
AddStategraphActionHandler("wilson", ActionHandler(ACTIONS.SW_FRESHEN, "doshortaction"))
AddStategraphActionHandler("wilson_client", ActionHandler(ACTIONS.SW_FRESHEN, "doshortaction"))
AddStategraphActionHandler("wilson", ActionHandler(ACTIONS.SW_UPGRADE, "dolongaction"))
AddStategraphActionHandler("wilson_client", ActionHandler(ACTIONS.SW_UPGRADE, "dolongaction"))
AddStategraphActionHandler("wilson", ActionHandler(ACTIONS.SW_WOVEN, "domediumaction"))
AddStategraphActionHandler("wilson_client", ActionHandler(ACTIONS.SW_WOVEN, "domediumaction"))
AddStategraphActionHandler("wilson", ActionHandler(ACTIONS.SW_CORDON, "dolongaction"))
AddStategraphActionHandler("wilson_client", ActionHandler(ACTIONS.SW_CORDON, "dolongaction"))
AddStategraphActionHandler("wilson", ActionHandler(ACTIONS.SW_PIGBOT, "dolongaction"))
AddStategraphActionHandler("wilson_client", ActionHandler(ACTIONS.SW_PIGBOT, "dolongaction"))
AddStategraphActionHandler("wilson", ActionHandler(ACTIONS.SW_TRADE, "give"))
AddStategraphActionHandler("wilson_client", ActionHandler(ACTIONS.SW_TRADE, "give"))

--=======================================
-- [[ ADD COMPONENT ACTION ]]
-- SCENE		using an object in the world                                        -- args: inst, doer, actions, right
-- USEITEM		using an inventory item on an object in the world                   -- args: inst, doer, target, actions, right
-- POINT		using an inventory item on a point in the world                     -- args: inst, doer, pos, actions, right, target
-- EQUIPPED		using an equiped item on yourself or a target object in the world   -- args: inst, doer, target, actions, right
-- INVENTORY	using an inventory item                                             -- args: inst, doer, actions, right
--=======================================

-- target是对象,inst是手中或鼠标上物品,doer是做动作的玩家,right是是否为右键
AddComponentAction("USEITEM", "sw_freshen", function(inst, doer, target, actions, right)
    if right and (target:HasTag("fresh") or target:HasTag("stale") or target:HasTag("spoiled")) then
        table.insert(actions, ACTIONS.SW_FRESHEN)
    end
end)
local prefabs = {
    "pocketwatch_weapon",
    "hambat",
    "abigail_flower",
    "abigail",
    "shieldofterror",
    "siestahut",
    "tent",
}
if _G.SHADOWWOVEN_SETS.ENABLEDMODS["musha"] then
    table.insert(prefabs, "mushasword_frost")
    table.insert(prefabs, "phoenixspear")
    table.insert(prefabs, "mushasword")
    table.insert(prefabs, "mushasword4")
    table.insert(prefabs, "frosthammer")
end
AddComponentAction("USEITEM", "sw_shard", function(inst, doer, target, actions, right)
    if table.contains(prefabs, target.prefab) or target:HasTag("sw_pigweed_pouch") or target:HasTag("abigail_flower") then
        table.insert(actions, ACTIONS.SW_UPGRADE)
    end
end)
AddComponentAction("USEITEM", "sw_woven", function(inst, doer, target, actions, right)
    if inst:HasTag("sw_woven") and target:HasTag("sw_weavable") then
        table.insert(actions, ACTIONS.SW_WOVEN)
    end
end)
AddComponentAction("USEITEM", "sw_cordon", function(inst, doer, target, actions, right)
    if inst:HasTag("sw_cordon") and target.prefab == "cave_entrance_open" then
        table.insert(actions, ACTIONS.SW_CORDON)
    end
end)
-- 关于物品组件的相关动作,用起来很舒服
AddComponentAction("USEITEM", "inventoryitem", function(inst, doer, target, actions, right)
    if target.prefab == "sw_pigbot" and inst.prefab == "sw_shadow_crown" then
        table.insert(actions, ACTIONS.SW_PIGBOT)
    end
    if target.prefab == "sw_pigbot" and inst.prefab == "alterguardianhat" then
        table.insert(actions, ACTIONS.SW_PIGBOT)
    end
    if target.prefab == "sw_shadow_tree" and inst.prefab == "sw_shadow_crown" then
        table.insert(actions, ACTIONS.SW_TRADE)
    end
    if target.prefab == "sw_moonlight_glass_tree" and inst.prefab == "alterguardianhat" then
        table.insert(actions, ACTIONS.SW_TRADE)
    end
end)

-- 动作兼容行为排队论
local queueractlist = {
    SW_UPGRADE = "allclick",
    SW_WOVEN = "allclick",
}
local actionqueuer_status, actionqueuer_data = pcall(require, "components/actionqueuer")
if actionqueuer_status then
    if AddActionQueuerAction and next(queueractlist) then
        for k, v in pairs(queueractlist) do
            AddActionQueuerAction(v, k, true)
        end
    end
end

-- 先创建动作再命名
STRINGS.ACTIONS.SW_FRESHEN = {
    GENERIC = STRINGS.SW_ACTIONS.SW_FRESHEN.GENERIC,
}

STRINGS.ACTIONS.SW_UPGRADE = {
    GENERIC = STRINGS.SW_ACTIONS.SW_UPGRADE.GENERIC,
    INFLOOD = STRINGS.SW_ACTIONS.SW_UPGRADE.INFLOOD,
}
STRINGS.CHARACTERS.GENERIC.ACTIONFAIL.SW_UPGRADE = {
    ALREADY_UPGRADED = STRINGS.SW_ACTIONS.SW_UPGRADE.ACTIONFAIL.ALREADY_UPGRADED,
    MISMATCH = STRINGS.SW_ACTIONS.SW_UPGRADE.ACTIONFAIL.MISMATCH,
}

STRINGS.ACTIONS.SW_WOVEN = {
    GENERIC = STRINGS.SW_ACTIONS.SW_WOVEN.GENERIC,
}

STRINGS.ACTIONS.SW_CORDON = {
    GENERIC = STRINGS.SW_ACTIONS.SW_CORDON.GENERIC,
}
STRINGS.CHARACTERS.GENERIC.ACTIONFAIL.SW_CORDON = {
    ALREADY_CORDON = STRINGS.SW_ACTIONS.SW_CORDON.ACTIONFAIL.ALREADY_CORDON,
}

STRINGS.ACTIONS.SW_PIGBOT = {
    GENERIC = STRINGS.SW_ACTIONS.SW_PIGBOT.GENERIC,
}
STRINGS.CHARACTERS.GENERIC.ACTIONFAIL.SW_PIGBOT = {
    ALREADY_UPDATED = STRINGS.SW_ACTIONS.SW_PIGBOT.ACTIONFAIL.ALREADY_UPDATED,
}

STRINGS.ACTIONS.SW_TRADE = {
    GENERIC = STRINGS.SW_ACTIONS.SW_TRADE.GENERIC,
}
STRINGS.CHARACTERS.GENERIC.ACTIONFAIL.SW_TRADE = {
    NOT_ELIGIBLE = STRINGS.SW_ACTIONS.SW_TRADE.ACTIONFAIL.NOT_ELIGIBLE,
}